﻿using StudentInfoSystem.Core.Interfaces;
using StudentInfoSystem.Core.MockImplementations;
using StudentInfoSystem.Core.Models;
using StudentInfoSystem.Core.Models.Enums;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;

namespace StudentInfoSystem.Tests.Services;

[TestClass]
public class MockStatisticsServiceTests
{
    private MockStudentService _studentService;
    private MockStatisticsService _statisticsService;

    [TestInitialize]
    public void TestInitialize()
    {
        // 创建学生服务 - 禁用随机数据生成
        //_studentService = new MockStudentService();
        //_studentService.SetFilePath($"test_{Guid.NewGuid()}.json");

        // 创建统计服务
        _statisticsService = new MockStatisticsService(_studentService);

        // 清空随机数据，只添加精确的测试数据
        _studentService.GetAll().Clear();
        AddTestStudents();
    }

    private void AddTestStudents()
    {
        // 精确控制的测试数据集
        var testStudents = new List<Student>
    {
        new Student { Id = "20230001", Name = "测试1", College = "计算机学院", Department = "软件工程", Class = "CS-201", Hometown = "北京" },
        new Student { Id = "20230002", Name = "测试2", College = "计算机学院", Department = "人工智能", Class = "AI-202", Hometown = "上海" },
        new Student { Id = "20230003", Name = "测试3", College = "计算机学院", Department = "软件工程", Class = "CS-201", Hometown = "广州" },
        new Student { Id = "20240001", Name = "测试4", College = "商学院", Department = "金融学", Class = "FIN-101", Hometown = "北京" },
        new Student { Id = "20240002", Name = "测试5", College = "商学院", Department = "会计学", Class = "ACC-102", Hometown = "深圳" }
    };

        foreach (var student in testStudents)
        {
            _studentService.Add(student);
        }
    }

    [TestMethod]
    public void GetCollegeDistribution_NoFilter_ReturnsCorrectCounts()
    {
        // Act
        var distribution = _statisticsService.GetCollegeDistribution();

        // Assert
        Assert.AreEqual(2, distribution.Keys.Count); // 仅计算机学院和商学院
        Assert.AreEqual(3, distribution["计算机学院"]);
        Assert.AreEqual(2, distribution["商学院"]);
    }

    [TestMethod]
    public void GetCollegeDistribution_WithCollegeFilter_ReturnsFilteredResults()
    {
        // Act
        var distribution = _statisticsService.GetCollegeDistribution("计算机学院");

        // Assert
        Assert.AreEqual(1, distribution.Keys.Count);
        Assert.AreEqual(distribution["计算机学院"], distribution.Values.Sum());
        Assert.IsTrue(distribution["计算机学院"] >= 3);
    }

    [TestMethod]
    public void GetCollegeDistribution_WithYearFilter_ReturnsFilteredResults()
    {
        // Act
        var distribution2023 = _statisticsService.GetCollegeDistribution(null, "2023");
        var distribution2024 = _statisticsService.GetCollegeDistribution(null, "2024");

        // Assert
        Assert.AreEqual(1, distribution2023.Keys.Count); // 仅计算机学院
        Assert.AreEqual(3, distribution2023["计算机学院"]);
        Assert.IsFalse(distribution2023.ContainsKey("商学院"));

        Assert.AreEqual(1, distribution2024.Keys.Count); // 仅商学院
        Assert.AreEqual(2, distribution2024["商学院"]);
        Assert.IsFalse(distribution2024.ContainsKey("计算机学院"));
    }

    [TestMethod]
    public void GetDepartmentDistribution_NoFilter_ReturnsCorrectCounts()
    {
        // Act
        var distribution = _statisticsService.GetDepartmentDistribution();

        // Assert
        Assert.IsTrue(distribution["软件工程"] >= 2);
        Assert.IsTrue(distribution["人工智能"] >= 1);
        Assert.IsTrue(distribution["金融学"] >= 1);
        Assert.IsTrue(distribution["会计学"] >= 1);
    }

    [TestMethod]
    public void GetDepartmentDistribution_WithCollegeFilter_ReturnsFilteredResults()
    {
        // Act
        var csDistribution = _statisticsService.GetDepartmentDistribution("计算机学院");
        var businessDistribution = _statisticsService.GetDepartmentDistribution("商学院");

        // Assert
        Assert.IsTrue(csDistribution["软件工程"] >= 2);
        Assert.IsTrue(csDistribution["人工智能"] >= 1);
        Assert.IsFalse(csDistribution.ContainsKey("金融学"));

        Assert.IsTrue(businessDistribution["金融学"] >= 1);
        Assert.IsTrue(businessDistribution["会计学"] >= 1);
        Assert.IsFalse(businessDistribution.ContainsKey("软件工程"));
    }

    [TestMethod]
    public void GetClassDistribution_CombinedFilters_ReturnsCorrectResults()
    {
        // Act
        var distribution = _statisticsService.GetClassDistribution("计算机学院", "2023");

        // Assert
        Assert.IsTrue(distribution["CS-201"] >= 2);
        Assert.IsTrue(distribution["AI-202"] >= 1);
        Assert.IsFalse(distribution.ContainsKey("FIN-101"));
    }

    [TestMethod]
    public void GetHometownDistribution_NoFilter_ReturnsCorrectCounts()
    {
        // Act
        var distribution = _statisticsService.GetHometownDistribution();

        // Assert
        Assert.IsTrue(distribution["北京"] >= 2);
        Assert.IsTrue(distribution["上海"] >= 1);
        Assert.IsTrue(distribution["广州"] >= 1);
        Assert.IsTrue(distribution["深圳"] >= 1);
    }

    [TestMethod]
    public void GetHometownDistribution_WithCollegeFilter_ReturnsFilteredResults()
    {
        // Act
        var distribution = _statisticsService.GetHometownDistribution("商学院");

        // Assert
        Assert.AreEqual(1, distribution["北京"]);
        Assert.AreEqual(1, distribution["深圳"]);
        Assert.IsFalse(distribution.ContainsKey("上海"));
    }

    [TestMethod]
    public void GetHometownDistribution_WithYearFilter_ReturnsFilteredResults()
    {
        // Act
        var distribution2023 = _statisticsService.GetHometownDistribution(null, "2023");
        var distribution2024 = _statisticsService.GetHometownDistribution(null, "2024");

        // Assert
        Assert.AreEqual(1, distribution2023["上海"]);
        Assert.AreEqual(1, distribution2023["广州"]);

        Assert.AreEqual(1, distribution2024["北京"]);
        Assert.AreEqual(1, distribution2024["深圳"]);
    }

    [TestMethod]
    public void AllMethods_WithInvalidFilters_ReturnEmptyOrPartialResults()
    {
        // Act
        var collegeDistribution = _statisticsService.GetCollegeDistribution("不存在学院");
        var deptDistribution = _statisticsService.GetDepartmentDistribution("计算机学院", "2099");
        var classDistribution = _statisticsService.GetClassDistribution("不存在学院", "2023");
        var hometownDistribution = _statisticsService.GetHometownDistribution("商学院", "2000");

        // Assert
        Assert.AreEqual(0, collegeDistribution.Count);
        Assert.AreEqual(0, deptDistribution.Count);
        Assert.AreEqual(0, classDistribution.Count);
        Assert.AreEqual(0, hometownDistribution.Count);
    }

    [TestMethod]
    public void DistributionMethods_ConsistentWithStudentCount()
    {
        // Arrange
        var allStudents = _studentService.GetAll().ToList();

        // Act
        var collegeTotal = _statisticsService.GetCollegeDistribution().Values.Sum();
        var deptTotal = _statisticsService.GetDepartmentDistribution().Values.Sum();
        var classTotal = _statisticsService.GetClassDistribution().Values.Sum();
        var hometownTotal = _statisticsService.GetHometownDistribution().Values.Sum();

        // Assert
        Assert.AreEqual(allStudents.Count, collegeTotal);
        Assert.AreEqual(allStudents.Count, deptTotal);
        Assert.AreEqual(allStudents.Count, classTotal);
        Assert.AreEqual(allStudents.Count, hometownTotal);
    }
}